//File: matrix.hpp
//Date: Sun Oct 17 2021
//Author: LiPeng(m201572398@alumni.hust.edu.cn)

#pragma once
#include <ostream>
#include "mat.hpp"

class Matrix : public Mat<double> {
    public:
        Matrix(){}

        Matrix(int rows, int cols):
            Mat<double>(rows, cols, 1) {}
        
        Matrix(const Mat<double>& r):
            Mat<double>(r) {}
        
        bool inverse(Matrix &ret) const;

        Matrix pseudo_inverse() const;

        Matrix transpose() const;

        Matrix prod(const Matrix& r) const;

        Matrix elem_prob(const Matrix& r) const;

        Matrix operator*(const Matrix& r) const
        {return prod(r);}

        void mult(double m){
            int n = pixels();
            double *p = ptr();
            for(int i=0; i<n; ++i){
                *p *= m;
                p++;
            }
        }

        Matrix operator - (const Matrix& r) const;
        Matrix operator + (const Matrix& r) const;

        bool SVD(Matrix & u, Matrix & s, Matrix & v) const;

        void normrot();

        double sqrtsum() const;

        Matrix col(int i) const;

        void zero();

        static Matrix I(int);

        friend std::ostream& operator << (std::ostream& os, const Matrix &m);
        
};
